package com.shop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.shop.AliPay.AliPayResource;
import com.shop.Redis.OrderKey;
import com.shop.Redis.RedisService;
import com.shop.dao.GoodsOrderInfoMapper;
import com.shop.pojo.Cart;
import com.shop.pojo.GoodsOrderInfo;
import com.shop.result.PayJsonResult;
import com.shop.util.BaseUtil;
import com.shop.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@Slf4j
@Service
public class AliPayServiceImpl {

    @Autowired
    private AliPayResource aliPayResource;

    @Autowired
    private RedisService redisService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private GoodsOrderInfoMapper goodsOrderInfoMapper;

    /**
     * 前往支付宝进行支付
     */
    public PayJsonResult goAlipay(Map<String,Object> dataParam) throws Exception{
        String merchantUserId = dataParam.get("merchantUserId").toString();
        String merchantUserName = dataParam.get("merchantUserName").toString();
        String merchantOrderId = dataParam.get("merchantOrderId").toString();
        String totalMoney = dataParam.get("totalMoney").toString();

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayResource.getGatewayUrl(),
                aliPayResource.getAppId(),
                aliPayResource.getMerchantPrivateKey(),
                "json",
                aliPayResource.getCharset(),
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getSignType());

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(aliPayResource.getReturnUrl());
        alipayRequest.setNotifyUrl(aliPayResource.getNotifyUrl());

        // 商户订单号, 商户网站订单系统中唯一订单号, 必填
        String out_trade_no = merchantOrderId;

        // 付款金额, 必填 单位元
        String total_amount = totalMoney;  // 测试用 1分钱

        // 订单名称, 必填
        String subject = merchantUserName+"-付款用户[" + merchantUserId + "]";

        // 商品描述, 可空, 目前先用订单名称
        String body = subject;

        // 该笔订单允许的最晚付款时间，逾期将关闭交易。
        // 取值范围：1m～15d。m-分钟，h-小时，d-天，1c-当天（1c-当天的情况下，无论交易何时创建，都在0点关闭）。
        // 该参数数值不接受小数点， 如 1.5h，可转换为 90m。
        String timeout_express = "15m";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String alipayForm = "";
        try {
            alipayForm = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

//        log.info("支付宝支付 - 前往支付页面, alipayForm: \n{}", alipayForm);
        return PayJsonResult.ok(alipayForm);
    }

    /**
     * 支付成功后的支付宝异步通知
     */
    public void alipayResult(HttpServletRequest request) throws Exception {
        log.info("支付成功后的支付宝异步通知");

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }

            //乱码解决，这段代码在出现乱码时使用
//       valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getCharset(),
                aliPayResource.getSignType()); //调用SDK验证签名

        if(signVerified) {//验证成功
            // 用户ID
            String subject = new String(request.getParameter("subject").getBytes("ISO-8859-1"),"UTF-8");
            String userId = subject.substring(subject.indexOf("[")+1,subject.indexOf("]"));

            // 商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
            // 交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
            // 付款金额
            String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

            if (trade_status.equals("TRADE_SUCCESS")){
                //支付成功后，从redis中获取对应用户的订单，更新交易状态和支付时间
                for (String orderId : out_trade_no.split(",")){

                    //获取redis中用户订单的商品信息
                    GoodsOrderInfo orderInfo = redisService.getKey(OrderKey.getOrder+userId,orderId,GoodsOrderInfo.class);
                    if(null == orderInfo){continue;}//避免非空情况下的异常

                    orderInfo.setStatus((byte)1);   //把订单状态设置为已支付
                    orderInfo.setPayDate(new Date());   //设置支付时间
                    goodsOrderInfoMapper.updateByPrimaryKey(orderInfo); //更新订单信息

                    //添加订单后，删除用户订单在redis中的缓存，避免后续查询中出现重复数据
                    redisService.deleteKey(userId,orderId);
                }

                /*支付成功后，从mongoDB中获取对应用户的订单，更新交易状态和支付时间*/
//                for (String orderId : out_trade_no.split(",")){
//
//                    /*获取MongoDB中用户订单的商品信息*/
//                    Query query = new Query();
//                    query.addCriteria(Criteria.where("orderId").is(orderId));
//
//                    /*查询MongoDB中单条的购物车商品数据*/
//                    Map<String,Object> map = mongoTemplate.findOne(query, Map.class, "goodsOrder");
//                    if(map != null){
//                        String cartJson = BaseUtil.toJson(map.get("goodsOrder"));
//                        GoodsOrderInfo orderInfo = JSONObject.parseObject(cartJson, GoodsOrderInfo.class);  //把数据转化为实体类数据
//                        if(null == orderInfo){  continue;}  //避免非空情况下的异常
//
//                        orderInfo.setStatus((byte)1);   //把订单状态设置为已支付
//                        orderInfo.setPayDate(new Date());//设置支付时间
//                        goodsOrderInfoMapper.updateByPrimaryKey(orderInfo); //更新订单信息
//
//                        /*添加订单后，删除用户订单在MongoDB中的缓存，避免后续查询中出现重复数据*/
//                        mongoTemplate.remove(query, GoodsOrderInfo.class);
//                    }
//                }

            }

            log.info("************* 支付成功(支付宝异步通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            log.info("* 用户ID: {}", userId);
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
            log.info("* 交易状态: {}", trade_status);
            log.info("*****************************************************************************");

        }else {
            //验证失败
            log.info("验签失败, 时间: {}", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
        }
    }

    /**
     * 支付成功后的支付宝返回通知
     */
    public String alipayReturn(HttpServletRequest request) throws Exception {

        log.info("支付成功后的支付宝返回通知");

        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//       valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params,
                aliPayResource.getAlipayPublicKey(),
                aliPayResource.getCharset(),
                aliPayResource.getSignType()); //调用SDK验证签名

        if(signVerified) {//验证成功
            String out_trade_no = request.getParameter("out_trade_no");     // 商户订单号
            String trade_no = request.getParameter("trade_no");                     // 支付宝交易号
            String trade_status = request.getParameter("trade_status");         // 交易状态
            String total_amount = request.getParameter("total_amount");      // 付款金额

            if (!StringUtils.isEmpty(out_trade_no)){
                out_trade_no = new String(out_trade_no.getBytes("ISO-8859-1"),"UTF-8");
            }
            if (!StringUtils.isEmpty(trade_no)){
                trade_no = new String(trade_no.getBytes("ISO-8859-1"),"UTF-8");
            }
            if (!StringUtils.isEmpty(trade_status)){
                trade_status = new String(trade_status.getBytes("ISO-8859-1"),"UTF-8");
            }
            if (!StringUtils.isEmpty(total_amount)){
                total_amount = new String(total_amount.getBytes("ISO-8859-1"),"UTF-8");
            }

            if (!StringUtils.isEmpty(trade_status) && trade_status.equals("TRADE_SUCCESS")){
                //获取到支付宝返回通知后，返回对应的信息给前端页面中进行渲染

            }

            log.info("************* 支付成功(支付宝返回通知) - 时间: {} *************", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));
            log.info("* 订单号: {}", out_trade_no);
            log.info("* 支付宝交易号: {}", trade_no);
            log.info("* 实付金额: {}", total_amount);
//            log.info("* 交易状态: {}", trade_status);
            log.info("*****************************************************************************");

            return "success";
        }else {
            //验证失败
            log.info("验签失败, 时间: {}", DateUtil.getCurrentDateString(DateUtil.DATETIME_PATTERN));

            return "fail";
        }
    }
}
